import pygame
import sys
import math
import random  # 新增：用于随机颜色

# 初始化 pygame
pygame.init()

# 设置窗口大小
width, height = 800, 600
screen = pygame.display.set_mode((width, height))

# 设置窗口标题
pygame.display.set_caption("Pygame 按角度发射方块")

# 定义颜色
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)

# 方块尺寸
block_size = 20

# 存储所有运动中的方块：每个元素包含 x, y, vx, vy
blocks = []

# 屏幕右下角作为目标参考点
target_point = (width, height)

# 游戏主循环
running = True
clock = pygame.time.Clock()

# ...

def random_color():
    """生成一个非黑色的随机颜色"""
    while True:
        color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
        if color != (0, 0, 0):  # 排除黑色
            return color

while running:
    clock.tick(60)  # 控制帧率为 60 FPS

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

            # 鼠标点击事件：发射一个方块
        if event.type == pygame.MOUSEBUTTONDOWN:
            mouse_pos = pygame.mouse.get_pos()

            # 发射起点设为左下角
            start_point = (0, height)

            # 计算从起点到鼠标的方向向量
            dx = mouse_pos[0] - start_point[0]
            dy = mouse_pos[1] - start_point[1]

            if dx == 0 and dy == 0:
                continue

            norm = math.hypot(dx, dy)
            dir_x = dx / norm
            dir_y = dy / norm

            speed = 3
            vx = dir_x * speed
            vy = dir_y * speed

            new_block = {
                'x': 0,
                'y': height - block_size,
                'vx': vx,
                'vy': vy,
                'color': random_color()  # 添加随机颜色
            }
            blocks.append(new_block)


    # 更新所有方块的位置
    # 更新所有方块的位置
    # 更新所有方块的位置
    # 更新所有方块的位置
        # 更新所有方块的位置
    for block in blocks:
        if block.get('state') == 'stopped':
            continue

        # 判断是否处于“仅下落”模式
        only_fall = block.get('only_fall', False)

        # 保持垂直方向的运动（即使进入 only_fall）
        block['y'] += block['vy']

        # 如果是 only_fall 模式，则不再横向移动
        if not only_fall:
            block['x'] += block['vx']
        else:
            block['vx'] = 0  # 强制清除水平速度

        # 构造当前方块的矩形
        current_rect = pygame.Rect(int(block['x']), int(block['y']), block_size, block_size)

        # 定义误差范围（像素）
        margin = 2

        # 仅下落模式：检查是否碰撞到已落地方块或触底
        if only_fall:
            # 预测下一步是否会落到某个方块上（带误差容忍）
            below_y = block['y'] + block_size + margin
            below_rect = pygame.Rect(int(block['x']), int(below_y), block_size, 1)  # 只检测底部一条线

            below_solid = False
            for other in blocks:
                if other is block or other.get('state') != 'stopped':
                    continue
                other_rect = pygame.Rect(int(other['x']), int(other['y']), block_size, block_size)
                if below_rect.colliderect(other_rect):
                    below_solid = True
                    break

            # 如果下方有支撑 或 触底，则停止
            if below_solid or block['y'] + block_size >= height:
                block['y'] = (height - block_size) if not below_solid else other['y'] - block_size
                block['vy'] = 0
                block['state'] = 'stopped'

        else:
            # 正常飞行状态下的碰撞检测（带边缘误差容忍）
            collided = False
            for other in blocks:
                if other is block or other.get('state') != 'stopped':
                    continue
                other_rect = pygame.Rect(int(other['x']), int(other['y']), block_size, block_size)

                # 使用 margin 扩展当前方块的碰撞区域
                expanded_rect = current_rect.inflate(margin * 2, margin * 2)
                if expanded_rect.colliderect(other_rect):
                    # 碰撞到已落地方块，进入仅下落模式
                    block['vx'] = 0
                    block['vy'] = abs(block['vy'])  # 向下掉落
                    block['only_fall'] = True
                    collided = True
                    break

            if not collided:
                # 边界反弹逻辑（保持不变）
                if block['y'] <= 0:
                    block['vy'] = abs(block['vy'])
                if block['x'] <= 0:
                    block['vx'] = abs(block['vx'])
                if block['x'] + block_size >= width:
                    block['vx'] = -abs(block['vx'])

        # 最终触底处理
        if block['y'] + block_size >= height:
            block['y'] = height - block_size
            block['vy'] = 0
            block['state'] = 'stopped'




    screen.fill(WHITE)

    # 绘制所有方块
    # 绘制所有方块时使用对应的颜色
    for block in blocks:
        rect = pygame.Rect(int(block['x']), int(block['y']), block_size, block_size)
        if block.get('state') == 'stopped':
            # 颜色变灰（降低亮度）
            gray_color = tuple(c // 2 for c in block['color'])
            pygame.draw.rect(screen, gray_color, rect)
        else:
            pygame.draw.rect(screen, block['color'], rect)

    # 更新显示
    pygame.display.flip()

# 退出 pygame
pygame.quit()
sys.exit()
